/**
 * 
 */
package com.zito;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.downlove.common.RequestContext;
import com.zito.manager.MasterSession;

/**
 * @author YunHai-Home
 * 
 */
public class MasterUrlFilter implements Filter {
	
	private ServletContext context;
	private List<String> ignoreURIs = new ArrayList<String>();
	private List<String> ignoreExts = new ArrayList<String>();
	private List<String> ignorePages = new ArrayList<String>();
	private final static String UTF_8 = "utf-8";
	private String login_page = "/login";
	private String virtual_directory = "";
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		// 自动编码处理

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		String req_upload_uri = request.getRequestURI();
		// 过滤URL文件
		for (String ignorePage : ignorePages) {
			if (req_upload_uri.endsWith(ignorePage)) {
				chain.doFilter(request, response);
				return;
			}
		}
		RequestContext rc = RequestContext.begin(this.context, request,
				response);
		// 获取当前URL
		String req_uri = rc.uri().indexOf(virtual_directory) == 0 ? rc.uri()
				.replace(virtual_directory, "") : rc.uri();
		try {
			// 过滤URL前缀
			for (String ignoreURI : ignoreURIs) {
				if (req_uri.startsWith(ignoreURI)) {
					chain.doFilter(rc.request(), rc.response());
					return;
				}
			}
			// 过滤URL后缀
			for (String ignoreExt : ignoreExts) {
				if (req_uri.endsWith(ignoreExt)) {
					chain.doFilter(rc.request(), rc.response());
					return;
				}
			}
			// 过滤URL文件
			for (String ignorePage : ignorePages) {
				if (req_uri.endsWith(ignorePage)) {
					chain.doFilter(rc.request(), rc.response());
					return;
				}
			}
			// 验证是否已经登陆
			if (MasterSession.get().userIsOnline()) {
		        try {
		            chain.doFilter(rc.request(), rc.response());
		            return;
		        } catch (Throwable t) {
		            t.printStackTrace();
		        }
			}
		
			rc.redirect(this.virtual_directory + this.login_page);
		} catch (SecurityException e) {
			// 如果有安全异常则提将URL加密后放到goto_page后面
			String login_page = e.getMessage() + "?goto_page="
					+ URLEncoder.encode(req_uri, UTF_8);
			rc.redirect(login_page);
		} finally {
			if (rc != null)
				rc.end();
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig cfg) throws ServletException {
		// 返回一个servlet对象
		this.context = cfg.getServletContext();
		// 某些URL前缀不予处理（例如 /img/***）
		String ignores = cfg.getInitParameter("ignore");
		if (ignores != null)
			for (String ig : StringUtils.split(ignores, ','))
				ignoreURIs.add(ig.trim());
		// 某些URL扩展名不予处理（例如 *.jpg）,web.xml中配置
		ignores = cfg.getInitParameter("ignoreExts");
		if (ignores != null)
			for (String ig : StringUtils.split(ignores, ','))
				ignoreExts.add('.' + ig.trim());
		// 某些URL文件不予处理（例如login.html）,web.xml中配置
		ignores = cfg.getInitParameter("ignorePages");
		if (ignores != null)
			for (String ig : StringUtils.split(ignores, ','))
				ignorePages.add(ig.trim());
		// 设置登录口
		String login = cfg.getInitParameter("login_page");
		if (login != null)
			login_page = login;
		// 查看是否配置了虚拟目录，因路径问题会导致应用不能发布在虚拟目录中
		String tmp_virtual_directory = cfg
				.getInitParameter("virtual_directory");
		if (tmp_virtual_directory != null)
			virtual_directory = tmp_virtual_directory;

	}

	protected void process(RequestContext req) throws ServletException,
			IOException {
		if (!MasterSession.get().userIsOnline()) {
			req.response().setContentType("text/html;charset=utf-8");
			req.redirect(this.login_page);
		}
		//System.out.println("然后呢？然后做了什么？？");
		return;
	}
}
